#include "header.h"

// 服务器的相关接口函数(TCP)
class ServerUtil 
{
public:
    // 获取监听套接字
    static int Getsock()
    {
        int sock = socket(AF_INET, SOCK_STREAM, 0);
        if (sock < 0)
            cerr << "监听套接字创建失败" << endl;

        // 因为服务器断开连接，导致服务器中有很多连接处于 TIME_WAIT 状态，导致服务器无法被重启
        int opt = 1;  // 设置地址复用, 就算服务器崩溃, 也可以马上重启
        setsockopt(sock, SOL_SOCKET, SO_REUSEADDR | SO_REUSEPORT, &opt, sizeof opt);
        cout << "成功创建套接字" << endl;
        return sock;
    }

    // 绑定这个服务器
    // 端口定死，默认 44444
    static void Bind(int sock)
    {
        struct sockaddr_in cursvr;
        socklen_t len = sizeof cursvr;
        memset(&cursvr, 0, len);

        cursvr.sin_family = AF_INET;
        cursvr.sin_port = htons(44444);
        cursvr.sin_addr.s_addr = INADDR_ANY;

        if (bind(sock, (const struct sockaddr*) &cursvr, len) != 0) 
            cerr << "服务器绑定失败" << endl;
    }

    // 开始监听
    static void Listen(int sock)
    {
        // 需要维护的全连接队列长度
        if (listen(sock, 5) != 0)
            cerr << "监视失败" << endl;
    }

    // 从监听队列中的连接队列中取出一个套接字
    static int Accept(int sock)
    {
        struct sockaddr_in peer;
        socklen_t len = sizeof peer;
        memset(&peer, 0, len);

        int nextfd = accept(sock, (struct sockaddr*) &peer, &len);
        if (nextfd < 0)
            cerr << "获取连接失败" << endl;
        return nextfd;
    }
};